/**
 * Created by xiaoz on 16/8/13.
 */

define(["utils","pageview","$","tip"],function(utils,PageView,$,Tip){


    var isPrevent = false;
    function PageViewManager(){
        var _this = this;
        this.pages = {};
        this.isForward = true;
        this.isInit = true;
        this.pagekeySeed = 0;
        this.isPrevent = false;
        this.$el =$("<div class='yy-root-view'></div>");
        this.$el.appendTo(document.body);

        $("<a id='yybluratag' style='position:absolute;left:-999px;top:-999px'></a>").appendTo(document.body);

        window.onhashchange=function(){
            _this.hashChange();
        };
        var touchTarget = null,activeClassName=null;//data-activecn
        $(document.body).bind("touchstart",function(e){
          touchTarget = e.target;
          activeClassName = touchTarget.getAttribute("data-activecn");
          while(touchTarget&&!activeClassName&&touchTarget.tagName.toUpperCase()!="BODY"){
            touchTarget = touchTarget.parentNode;
            activeClassName = touchTarget.getAttribute("data-activecn");
            if(activeClassName){
              break;
            }
          }
          if(touchTarget&&activeClassName){
            $(touchTarget).addClass(activeClassName);
          }
        });
        $(document.body).bind("touchend",function(){
          if(touchTarget&&activeClassName){
            $(touchTarget).removeClass(activeClassName);
          }
          touchTarget = null;
        });
    }

    PageViewManager.prototype = {
        blur:function(){
          $("#yybluratag").focus();
          if(document.activeElement){
            document.activeElement.blur();
          }
        },
        showTip:function(config){
          this.Tip = new Tip(this.$el);
          this.Tip.show(config);
        },

        start:function(config){
            utils.appConfig = config;
            utils.customerComponents = config.customerComponents||{};
            config.baseSize = config.baseSize||{"width":320,"height":568};
            utils.baseSize.width = config.baseSize.width;
            utils.baseSize.height = config.baseSize.height;
            this.config = config;
            var toPage = this.getPageNameFromUrl();
            if(!toPage){
                this.go(config.root,this.getParamsFromUrl());
            }else{
                this.hashChange();
                var pageKeyArr = toPage.split("$$");
                if(pageKeyArr.length==2){
                  this.pagekeySeed = parseInt(pageKeyArr[1]);
                }
            }
        },
        showPageKeyDict:{},
        regeistShowPageInRouter:function(pageKey){
          this.showPageKeyDict[pageKey] = true;
        },
        hashChange:function(){

            var _this = this;
            if(isPrevent){
              isPrevent = false;
              return ;
            }
            var toPage = this.getPageNameFromUrl();
            var fromPageInstance = this.pages[this.fromPage];

            if(fromPageInstance&&this.showPageKeyDict[this.fromPage]===true&&fromPageInstance.showpage_wrapper){
              fromPageInstance.hideCurShowPage();
              delete this.showPageKeyDict[this.fromPage];
              isPrevent = true;
              window.history.go(1);
              return;
            }

            if(fromPageInstance){
              var beforeleaveMethod = fromPageInstance.plugin.onPageBeforeLeave;
              if(beforeleaveMethod){
                var beforeleavePrevent = beforeleaveMethod.call(fromPageInstance.plugin,fromPageInstance,{isForward:this.isForward});
                if(beforeleavePrevent===false){
                  isPrevent = true;
                  window.history.go(1);
                  return;
                }
              }
            }
            // console.log("from : "+this.fromPage+(this.isForward?"前进到":"后退")+toPage);
            if(this.config.routerChange){
              this.config.routerChange({
                fromPage:this.fromPage,
                toPage:toPage,
                isForward:this.isForward
              });
            }
            var toPageInstance = this.pages[toPage];
            if(fromPageInstance&&!toPageInstance){
              fromPageInstance.showLoadingProgressbar();
            }
            this.blur();
            this._renderNextPage(toPage,this.fromPage,this.isForward,fromPageInstance,function(fromPage,_isForWard,_fromPageInstance){
              if(fromPage){
                  var fromPageInstance = _this.pages[fromPage];
                  if(fromPageInstance){
                      var fromClassName ="yy-pageview displayflex "+(_isForWard? "left-out":"right-out");
                      fromPageInstance.$el[0].className = fromClassName;
                  }
              }
              if(_fromPageInstance){
                 _fromPageInstance.hideLoadingProgressbar();
              }
              if(_isForWard){
                  _this.fromPage = toPage;
              }else{
                window.setTimeout(function(){
                    if(fromPage){
                        _this.pages[fromPage].destory();
                        delete _this.pages[fromPage];
                    }
                    _this.fromPage = toPage;
                },300);
              }
            },function(_fromPageInstance){
              isPrevent = true;
              window.history.go(-1);
              if(_fromPageInstance){
                _fromPageInstance.hideLoadingProgressbar();
              }
            });

        },
        _renderNextPage:function(pageKey,fromPage,isForward,fromPageInstance,success,error){
          var _this = this;
          var pageInstance = this.pages[pageKey];
          if(!pageInstance){
            _this.getPageConfigByPageKey(pageKey,function(pageConfig){
              pageConfig.prePageView =isForward? fromPageInstance:null;
              var pageInstance =  _this.createPageView(pageConfig);
              _this.pages[pageKey] = pageInstance;
              if(_this.isInit){
                  _this.isInit = false;
              }else{
                  pageInstance.$el[0].className ="yy-pageview displayflex "+(_this.isForward? "right-in":"left-in");
              }
              _this.isForward = false;
              _this.$el.append(pageInstance.$el);

              success(fromPage,isForward,fromPageInstance);
            },function(){
              if(error){
                error(fromPageInstance);
              }

            });
          }else{
            if(!this.isForward){
                var toClassName ="yy-pageview displayflex left-in";
                pageInstance.$el[0].className = toClassName;

                var onResumeMethod = pageInstance.plugin.onPageResume;
                if(onResumeMethod){
                   onResumeMethod.call(pageInstance.plugin,pageInstance,{isForward:false});
                }

            }
            success(fromPage,isForward);
            this.isForward = false;
          }
        },
        createPageView:function(pageConfig){
          return new PageView(pageConfig);
        },
        getPageNameFromUrl:function(){
            var nameArr = window.location.hash.split("#");
            if(nameArr.length!=2){
                return this.rootPageKey;
            }
            var s = nameArr[1];
            var sArr = s.split("?");
            return sArr[0];
        },
        getParamsStrFromUrl:function(){
          var Arr = window.location.href.split("?");
          var str = Arr[Arr.length-1];
          if(!str){
            return null;
          }
          var str_arr = str.split("#");
          return str_arr[0];
        },
        getParamsFromUrl:function(){
           var paraStr = this.getParamsStrFromUrl();
           if(!paraStr){return null;}
           var re= {};
           var paramsArr =paraStr.split("&");
           for(var i=0,j=paramsArr.length;i<j;i++){
             var key_value_arr = paramsArr[i].split("=");
             if(key_value_arr.length==2){
               re=re||{};
               re[key_value_arr[0]] = key_value_arr[1];
             }
           }
           return re;
       },
       tabSeleced:function(pagename,isInit){
         if(!isInit){
           isPrevent = true;
         }
         var params = this.getParamsFromUrl()||{};
         params.$$pn = pagename;
         var paramsArr = [];
         for(var key in params){
             paramsArr.push(key+"="+params[key]);
         }
         var pageKey = this.getPageNameFromUrl();
         if(paramsArr.length>0){
            location.replace(location.href.split("#")[0] + '#' +pageKey+"?"+paramsArr.join("&"));
         }else{
            location.replace(location.href.split("#")[0] + '#' +pageKey);
         }
       },
       goBack:function(){
           this.isForward = false;
           window.history.go(-1);
       },
        go:function(pageKey,params){
            this.isForward = true;
            isPrevent = false;
            if(this.isInit){
                this.rootPageKey = pageKey;

            }else{

            }
            params = params||{};
            var paramsArr = [];
            for(var key in params){
                paramsArr.push(key+"="+params[key]);
            }
            pageKey = this._getUniquePageKey(pageKey);
            if(paramsArr.length>0){
                location.hash = pageKey+"?"+paramsArr.join("&");
            }else{
                location.hash = pageKey;
            }

        },
        _getUniquePageKey:function(pagekey){
            var hasSameKeyInStack = false;
            for(var key in this.pages){
                var key_arr = key.split("$$");
                if(key_arr[0]==pagekey){
                    this.pagekeySeed += 1;
                    hasSameKeyInStack = true;
                    break;
                }
            }
            return hasSameKeyInStack?(pagekey+"$$"+this.pagekeySeed):pagekey;
        },
        _getPageConfigSuccess:function(pageKey,pageConfig,success){
          pageConfig = utils.copy(pageConfig);
          pageConfig.type= "pageview";
          pageConfig.pageKey = pageKey;
          pageConfig.$$params = this.getParamsFromUrl();
          pageConfig.$$pageManager = this;
          success(pageConfig);
        },
        getPageConfigByPageKey:function(pageKey,success,error){
            var _this = this;
            var page_path = "./pages/"+pageKey.split("$$")[0];
            var _pageConfig = utils.getPageConfigByPagePath(page_path);
            if(_pageConfig){
              this._getPageConfigSuccess(pageKey,_pageConfig,success);
              return;
            }
            // var randomPath = page_path+".js?t="+(new Date()).valueOf();//避免网络断开请求失败后 无论是否再次联网都失败
            require([page_path],function(pageConfig){
              pageConfig = utils.setPageConfigByPagePath(page_path,pageConfig);
              _this._getPageConfigSuccess(pageKey,pageConfig,success);
            },function(){
              if(error){
                error(pageKey);
              }
            });
        }

    };
    return new PageViewManager();
});
